package com.xuef.ibatis.binding;

import com.xuef.ibatis.session.SqlSession;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by xuefengDong: moveb
 * On 2019/4/26- 16:10
 * 负责创建具体Mapper接口代理对象的工厂类
 */
public class MapperProxyFactory<T> {
    //具体Mapper接口的Class对象
    private final Class<T> mapperInterface;

    //该接口下面方法的缓存 key是方法对象 value是对接口中方法对象的封装
    private Map<Method, MapperMethod> methodCache = new ConcurrentHashMap<Method, MapperMethod>();

    public MapperProxyFactory(Class<T> mapperInterface) {
        this.mapperInterface = mapperInterface;
    }
    public Class<T> getMapperInterface() {
        return mapperInterface;
    }
    public Map<Method, MapperMethod> getMethodCache() {
        return methodCache;
    }

    @SuppressWarnings("unchecked")
    protected T newInstance(MapperProxy<T> mapperProxy) {
        return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(),
                new Class[] { mapperInterface }, mapperProxy);
    }

    //在这里传入sqlSession 创建一个Mapper接口的代理对象
    public T newInstance(SqlSession sqlSession) {
        //在这里创建了MapperProxy对象 这个类实现了JDK的动态代理接口 InvocationHandler
        final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
        return newInstance(mapperProxy);
    }

}
